package com.exampl.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.exampl.common.CustomException;
import com.exampl.common.R;
import com.exampl.domain.Category;
import com.exampl.domain.Dish;
import com.exampl.domain.Setmeal;
import com.exampl.domain.SetmealDish;
import com.exampl.dto.SetmealDishDto;
import com.exampl.dto.SetmealDto;
import com.exampl.service.CategoryService;
import com.exampl.service.DishService;
import com.exampl.service.SetmealDishService;
import com.exampl.service.SetmealService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/setmeal")
public class SetMealController {

    @Autowired
    SetmealService setmealService;

    @Autowired
    SetmealDishService setmealDishService;

    @Autowired
    CategoryService categoryService;

    @Autowired
    DishService dishService;

    // 添加套餐
    @PostMapping
    @CacheEvict(value = "setmealCache", key = "#setmealDto.categoryId + '_1'")
    public R<String> save(@RequestBody SetmealDto setmealDto){
        setmealService.saveWithDish(setmealDto);
        return R.success("添加成功！");
    }

    // 显示套餐
    @GetMapping("/page")
    public R<Page<SetmealDto>> page(Integer page, Integer pageSize, String name){
        Page<Setmeal> setmealPage = new Page<Setmeal>(page, pageSize);
        Page<SetmealDto> setmealDtoPage = new Page<SetmealDto>();
        // 添加查询条件
        LambdaQueryWrapper<Setmeal> lqw = new LambdaQueryWrapper<Setmeal>();
        lqw.like(name != null, Setmeal::getName, name);
        lqw.orderByDesc(Setmeal::getUpdateTime);
        setmealService.page(setmealPage, lqw);
        // 赋值数据，除去records
        BeanUtils.copyProperties(setmealPage, setmealDtoPage, "records");
        // 获取数据
        List<Setmeal> setmeals = setmealPage.getRecords();
        List<SetmealDto> list =setmeals.stream().map((data) -> {
            SetmealDto dto = new SetmealDto();
            // 复制基础变量
            BeanUtils.copyProperties(data, dto);
            Long id = data.getCategoryId();
            Category category = categoryService.getById(id);
            // 获取分类名称
            String name1 = category.getName();
            dto.setCategoryName(name1);
            return dto;
        }).collect(Collectors.toList());
        setmealDtoPage.setRecords(list);
        return R.success(setmealDtoPage);
    }

    // 删除套餐，若在售则无法删除
    @DeleteMapping
    public R<String> delete(@RequestParam List<Long> ids){
        // 判断是否在售
        LambdaQueryWrapper<Setmeal> lqw = new LambdaQueryWrapper<Setmeal>();
        lqw.in(Setmeal::getId, ids);
        lqw.eq(Setmeal::getStatus, 1);
        int count = setmealService.count(lqw);
        if(count > 0){
            throw new CustomException("该套餐在售，无法删除！");
        }
        // 先删除套餐具体菜品
        for(Long id:ids){
            LambdaQueryWrapper<SetmealDish> dishLambdaQueryWrapper = new LambdaQueryWrapper<SetmealDish>();
            dishLambdaQueryWrapper.eq(SetmealDish::getSetmealId, id);
            setmealDishService.remove(dishLambdaQueryWrapper);
        }
        // 删除套餐
        setmealService.removeByIds(ids);
        return R.success("删除成功！");
    }

    // 修改状态
    @PostMapping("/status/{status}")
    @CacheEvict(value = "setmealCache", allEntries = true)  // 全部删除
    public R<String> updateStatus(@PathVariable Integer status, @RequestParam List<Long> ids){
        List<Setmeal> setmeals = new ArrayList<Setmeal>();
        for(Long id:ids){
            // 判断套餐中的菜品是否停售，若停售则无法进行启售
            if(status == 1){
                LambdaQueryWrapper<SetmealDish> lqw = new LambdaQueryWrapper<SetmealDish>();
                lqw.eq(SetmealDish::getSetmealId, id);
                List<SetmealDish> dishes = setmealDishService.list(lqw);
                for(SetmealDish dish:dishes){
                    Long aLong = dish.getDishId();
                    Dish dish1 = dishService.getById(aLong);
                    Integer status1 = dish1.getStatus();
                    // 停售则返回ture
                    if(status1 == 0){
                        throw new CustomException("需要启售的套餐中包含停售的菜品！");
                    }
                }
            }
            Setmeal setmeal = new Setmeal();
            setmeal.setId(id);
            setmeal.setStatus(status);
            setmeals.add(setmeal);
        }
        setmealService.updateBatchById(setmeals);
        return R.success("状态修改成功！");
    }

    // 回显数据
    @GetMapping("/{setmealId}")
    public R<SetmealDto> reserve(@PathVariable Long setmealId){
        SetmealDto setmealDto = setmealService.getWithDish(setmealId);
        return R.success(setmealDto);
    }

    // 修改数据
    @PutMapping
    @CacheEvict(value = "setmealCache", key = "#setmealDto.categoryId + '_1'")  // 局部删除
    public R<String> update(@RequestBody SetmealDto setmealDto){
        setmealService.updateWithDish(setmealDto);
        return R.success("修改成功！");
    }

    // 显示该分类中的套餐
    @GetMapping("/list")
    @Cacheable(value = "setmealCache", key = "#categoryId + '_' + #status")
    public R<List<Setmeal>> listR(Long categoryId, Integer status){
        List<Setmeal> setmeals = null;
        LambdaQueryWrapper<Setmeal> lqw = new LambdaQueryWrapper<Setmeal>();
        lqw.eq(Setmeal::getCategoryId, categoryId);
        lqw.eq(Setmeal::getStatus, status);
        setmeals = setmealService.list(lqw);
        return R.success(setmeals);
    }

    // 显示套餐详细
    @GetMapping("/dish/{setmealId}")
    public R<List<SetmealDishDto>> dish(@PathVariable Long setmealId){
        LambdaQueryWrapper<SetmealDish> lqw = new LambdaQueryWrapper<>();
        lqw.eq(setmealId != null, SetmealDish::getSetmealId, setmealId);
        List<SetmealDish> dishList = setmealDishService.list(lqw);
        List<SetmealDishDto> dishDtoList = dishList.stream().map((data) -> {
            SetmealDishDto dishDto = new SetmealDishDto();
            // 复制setmealDish复制给setmealDishDto
            BeanUtils.copyProperties(data, dishDto);
            // 获取图片路径
            Dish dish = dishService.getById(dishDto.getDishId());
            String image = dish.getImage();
            dishDto.setImage(image);
            return dishDto;
        }).collect(Collectors.toList());
        return R.success(dishDtoList);
    }
}
